package shopping.commons;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by IntelliJ IDEA.
 * User: mazhao
 * Date: 2010/11/06
 * Time: 16:57:20
 * To change this template use File | Settings | File Templates.
 */
public class SecurityInterceptor implements Interceptor {
    private Log log = LogFactory.getLog(this.getClass());

    private Map<Pattern, Pattern> sm = buildSecurityMap();

    @Override
    public void destroy() {
        log.debug("security interceptor destroyed!");
    }

    @Override
    public void init() {
        log.debug("security interceptor initialized");
    }

    @Override
    public String intercept(ActionInvocation ai) throws Exception {
        HttpServletRequest request = ServletActionContext.getRequest();
        String requestUri = request.getRequestURI().substring(request.getContextPath().length());
        log.debug("request uri:" + requestUri);

        if (canAccess(requestUri)) {
            log.debug("can access, continue invocation");
            return ai.invoke();
        } else {
            log.debug("can not access, return to authorize failed.");
            return AUTHORIZED_FAILED;
        }
    }

    public static final String AUTHORIZED_FAILED = "authorizeFailed";

    private boolean canAccess(String uri) {

        log.debug("enter can access branch!");

        Iterator<Map.Entry<Pattern, Pattern>> it = sm.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<Pattern, Pattern> ent = it.next();
            Pattern uriPtn = ent.getKey();
            Pattern rolePtn = ent.getValue();
            log.debug("uriPtn.matcher(" + uri + ").matches():" + uriPtn.matcher(uri).matches());
            if (uriPtn.matcher(uri).matches()) {
                String role = Util.Security.retriveUserFromSession() != null ? Util.Security.retriveUserFromSession().getRole() : "";
                log.debug("rolePtn.matcher(" + role + ").matches():" + rolePtn.matcher(role).matches());
                boolean ret = rolePtn.matcher(role).matches();
                log.debug("exit can access branch with " + ret);
                return ret;
            }
        }
        log.debug("exit can access branch with true " );
        return true;
    }


    /**
     * build access control here.
     * @return access control map.
     */
    private Map<Pattern, Pattern> buildSecurityMap() {
        Map<Pattern, Pattern> securityMap = new HashMap<Pattern, Pattern>();
        securityMap.put(Pattern.compile("^/customer/.*"), Pattern.compile(".+"));
        securityMap.put(Pattern.compile("^/management/.*"), Pattern.compile("^admin"));
        return securityMap;
    }

    public static void main(String[] args) {
        //Pattern ptn = Pattern.compile("^/customer/.*");
        //boolean ret = ptn.matcher("/customer/order.action").matches();
//        Pattern ptn = Pattern.compile("^/management/.*");
//        boolean ret = ptn.matcher("/management/order.action").matches();

        Pattern ptn = Pattern.compile("^admin");
        boolean ret = ptn.matcher("admin").matches();
        System.out.println("ret:" + ret);
    }

}
